<?php

namespace app\admin\middleware;

use app\common\business\DataAuth;
use app\common\business\SysDept;
use app\common\model\mysql\SysOperLog;

class LogMiddleware
{
    public function handle($request, \Closure $next)
    {
        $startTime = microtime(true); // 记录开始时间
        $response = $next($request);
        $endTime = microtime(true); // 记录结束时间
        // 检查是否可能是更新操作
        if (in_array($request->method(), ['PUT', 'POST', 'DELETE'])) {
            // 记录日志
            $this->recordLog($request, $response, $endTime - $startTime);
        }
        return $response;
    }

    protected function recordLog($request, $response, $duration){
        $logData = $this->prepareLogData($request, $response, $duration);
        if($logData){
            (new SysOperLog())->addOperLog($logData);
        }
    }

    private function prepareLogData($request, $response, $duration){
        $pathInfo = strtolower($request->pathinfo());
        $title = $this->getTitleFromPathInfo($pathInfo);
        if($title === "XX XX"){
            return [];
        }
        $pageSource = $this->getPageSourceFromPathInfo($pathInfo,$request);

        $ip = $request->ip();
        $method = $request->method();
        $uri = $request->baseUrl();
        $params = json_encode($request->param(), JSON_UNESCAPED_UNICODE);

        $responseData = $this->getResponseData($response);
        $msg = $responseData['msg'] ?? 'No message';
        $code = $responseData['code'] ?? 0;

        $userData = (new DataAuth())->getUserDetails();
        $deptData = $this->getDeptData($userData['deptId']);

        $business_type = $this->getBusinessType($method);

        return [
            'title' => $title,
            'business_type' => $business_type,
            'method' => $uri, // 注意：这里可能应该是 $method 而不是 $uri
            'request_method' => $method,
            'operator_type' => 1,
            'oper_name' => $userData['userName'],
            'dept_name' => $deptData['dept_name'] ?? 'Unknown Dept',
            'oper_url' => $pageSource,
            'oper_ip' => $ip,
            'oper_location' => '内网IP',
            'oper_param' => $params,
            'json_result' => json_encode(['msg' => $msg, 'code' => $code], JSON_UNESCAPED_UNICODE),
            'status' => 0,
            'error_msg' => null,
            'oper_time' => date("Y-m-d H:i:s", time()),
            'cost_time' => round($duration * 1000),
        ];
    }

    private function getTitleFromPathInfo($pathInfo)
    {
        $titleMap = [
            'sysuser'       => '用户管理',
            'sysrole'       => '角色管理',
            'sysmenu'       => '菜单管理',
            'sysdept'       => '部门管理',
            'syspost'       => '岗位管理',
            'sysdicttype'   => '字典管理',
            'sysconfig'     => '参数设置',
            'sysnotice'     => '通知公告',
            'sysoperlog'    => '操作日志',
            'syslogininfor' => '登录日志',
        ];
        foreach ($titleMap as $key => $value) {
            if (strpos($pathInfo, $key) !== false) {
                return $value;
            }
        }
        return 'XX XX'; // 默认标题
    }

    private function getPageSourceFromPathInfo($pathInfo, $request)
    {
        $pathInfoToPageSourceMap = [
            'sysuser'       => '/system/user',
            'sysrole'       => '/system/role',
            'sysmenu'       => '/system/menu',
            'sysdept'       => '/system/dept',
            'syspost'       => '/system/post',
            'sysdicttype'   => '/system/dict',
            'sysconfig'     => '/system/config',
            'sysnotice'     => '/system/notice',
            'sysoperlog'    => '/system/log/operlog',
            'syslogininfor' => '/system/log/logininfor',
        ];
        foreach ($pathInfoToPageSourceMap as $key => $value) {
            if (strpos($pathInfo, $key) !== false) {
                return $value;
            }
        }
        return $request->baseUrl(); // 默认页面源
    }

    private function getResponseData($response)
    {
        $content = $response->getContent();
        $data = json_decode($content, true);
        if (json_last_error() !== JSON_ERROR_NONE) {
            // 处理解析错误
            return [];
        }
        return $data;
    }

    private function getDeptData($deptId)
    {
        return (new SysDept())->getFindNormalDept(['dept_id' => $deptId]);
    }

    private function getBusinessType($method)
    {
        // 使用关联数组映射HTTP方法到业务类型
        $methodTypeMap = [
            'PUT' => 2,
            'POST' => 1,
            'DELETE' => 3,
        ];
        return $methodTypeMap[$method] ?? 0;
    }
}
